package org.jsola.contract.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.jsola.contract.common.ExampleKit;
import org.jsola.contract.common.PdfUtil;
import org.jsola.contract.constant.ContractConstants;
import org.jsola.contract.core.MockMultipartFile;
import org.jsola.contract.dao.IAppendixDAO;
import org.jsola.contract.dto.AppendixAddDTO;
import org.jsola.contract.dto.AppendixUpdateDTO;
import org.jsola.contract.entity.AppendixDO;
import org.jsola.contract.entity.ContractDO;
import org.jsola.contract.query.AppendixQuery;
import org.jsola.contract.service.IAppendixService;
import org.jsola.contract.service.IContractService;
import org.jsola.contract.vo.AppendixListSiteIdVO;
import org.jsola.contract.vo.AppendixListVO;
import org.jsola.contract.vo.AppendixVO;
import org.jsola.contract.vo.ContractVO;
import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.file.core.FileProperties;
import org.jsola.file.entity.FileVersionDO;
import org.jsola.file.service.ISiteFileService;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 合同文件
 *
 * @author JanusMix
 */
@Service("contractAppendixServiceImpl")
public class AppendixServiceImpl implements IAppendixService {

    @Autowired
    private IAppendixDAO appendixDAO;

    @Autowired
    private IContractService contractService;

    @Autowired
    private ISiteFileService siteFileService;

    @Autowired
    private FileProperties fileProperties;

    @Override
    @Transactional(value = ContractConstants.TX, rollbackFor = Exception.class)
    public AppendixVO save(AppendixAddDTO appendixAddDTO, TokenUser tokenUser) {
        // 转DO
        AppendixDO appendixDO = appendixAddDTO.to(AppendixDO.class);
        // 保存
        appendixDO = save(appendixDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return appendixDO.to(AppendixVO.class);
    }

    @Override
    @Transactional(value = ContractConstants.TX, rollbackFor = Exception.class)
    public int update(AppendixUpdateDTO appendixUpdateDTO, TokenUser tokenUser) {
        //转DO
        AppendixDO appendixDO = appendixUpdateDTO.to(AppendixDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(appendixDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = ContractConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, Long... appendixIds) {
        return deleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) appendixIds);
    }


    @Override
    public AppendixVO selectById(Long appendixId, String siteId) {
        AppendixDO appendixDO = selectDOById(appendixId, siteId);
        if (appendixDO == null) {
            return null;
        }
        return appendixDO.to(AppendixVO.class);
    }

    @Override
    public List<AppendixListVO> select(AppendixQuery appendixQuery, String siteId) {
        List<AppendixDO> appendixDOList = selectDO(appendixQuery, siteId);
        if (CollectionUtils.isEmpty(appendixDOList)) {
            return appendixDOList == null ? null : new ArrayList<>();
        }
        return appendixDOList.stream()
                .map(appendixDO -> appendixDO.to(AppendixListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(AppendixQuery appendixQuery, String siteId) {
        Example example = buildExample(appendixQuery, siteId);
        return appendixDAO.selectCountByExample(example);
    }

    @Override
    public Page<AppendixListVO> selectPage(AppendixQuery appendixQuery, String siteId) {
        Example example = buildExample(appendixQuery, siteId);
        Page<AppendixDO> page = appendixDAO.selectPageByExample(example,
                appendixQuery.getPageNo(),
                appendixQuery.getPageSize());

        return page.to(AppendixListVO.class);
    }

    @Override
    public AppendixDO selectDOById(Long appendixId, String siteId) {
        return listById(appendixId, siteId);
    }

    @Override
    public List<AppendixDO> selectDO(AppendixQuery appendixQuery, String siteId) {
        Example example = buildExample(appendixQuery, siteId);
        return appendixDAO.selectByExample(example);
    }

    @Override
    public AppendixDO selectByContractId(Long contractId, String siteId) {
        Example example = new Example(AppendixDO.class);
        example.and()
                .andEqualTo("siteId", siteId)
                .andEqualTo("contractId", contractId);
        example.orderBy("id").desc();
        List<AppendixDO> appendixDOList = appendixDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(appendixDOList)) {
            return null;
        }
        return appendixDOList.get(0);
    }

    @Override
    public AppendixVO selectVOByContractId(Long contractId, String siteId) {
        ContractVO contractVO = contractService.selectById(contractId, siteId);
        ContractDO contractDO = contractVO.to(ContractDO.class);
        ParamException.notNull(contractVO, "合同不存在或已删除，请刷新重试!");
        AppendixDO appendixDO = selectByContractId(contractId, siteId);
        ParamException.notNull(appendixDO, "合同文件不存在或还没有生成，请稍后刷新重试!");
        AppendixVO appendixVO = appendixDO.to(AppendixVO.class);
        appendixVO.setContractVO(contractVO);
        contractDO.setIsView(true);
        contractService.updateByIdSelective(contractDO);
        return appendixVO;
    }

    @Override
    public List<AppendixDO> listByContractIds(List<Long> contractIdList, String siteId) {
        if (CollectionUtils.isEmpty(contractIdList)) {
            return new ArrayList<>();
        }
        Example example = new Example(AppendixDO.class);
        example.and()
                .andIn("contractId", contractIdList)
                .andEqualTo("siteId", siteId);
        return appendixDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = ContractConstants.TX, rollbackFor = Exception.class)
    public void deleteByContractId(Long contractId, TokenUser tokenUser) {
        Example example = new Example(AppendixDO.class);
        example.and()
                .andEqualTo("contractId", contractId)
                .andEqualTo("siteId", tokenUser.getSiteId());
        appendixDAO.deleteByExample(example);
    }

    @Override
    public void deleteByContractIds(List<Long> contractIds, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(contractIds)) {
            return;
        }
        Example example = new Example(AppendixDO.class);
        example.and()
                .andIn("contractId", contractIds)
                .andEqualTo("siteId", tokenUser.getSiteId());
        appendixDAO.deleteByExample(example);
    }

    @Override
    @Transactional(value = ContractConstants.TX, rollbackFor = Exception.class)
    public void renameContractPdf(TokenUser tokenUser) {
        Example example = new Example(AppendixDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId());
        List<AppendixDO> appendixList = appendixDAO.selectByExample(example);
        if (!CollectionUtils.isEmpty(appendixList)) {
            appendixList.parallelStream().forEach(
                    appendixDO -> {
                        ContractDO contractDO = contractService.selectDOById(appendixDO.getContractId(), tokenUser.getSiteId());
                        if (Objects.nonNull(contractDO)) {
                            String pdfName = contractDO.getName();
                            if (StringUtils.isNotEmpty(contractDO.getSignNo())) {
                                pdfName = pdfName + "(" + contractDO.getSignNo() + ").pdf";
                                // 更换名字
                                siteFileService.renameSiteFileByUrl(appendixDO.getPath(), pdfName, tokenUser);
                            }
                        }
                    }
            );
        }
    }

    @Override
    public List<AppendixListSiteIdVO> listAllNoSiteId(AppendixQuery appendixQuery) {
        if (appendixQuery.getContractId() == null) {
            throw new ParamException("合同id不能为空");
        }
        Example example = new Example(AppendixDO.class);
        example.and().andEqualTo("contractId", appendixQuery.getContractId());
        if (appendixQuery.getName() != null) {
            example.and().andEqualTo("name", appendixQuery.getName());
        }
        if (appendixQuery.getCurrentPage() != null) {
            example.and().andEqualTo("currentPage", appendixQuery.getCurrentPage());
        }
        if (appendixQuery.getPath() != null) {
            example.and().andEqualTo("path", appendixQuery.getPath());
        }
        if (appendixQuery.getPassword() != null) {
            example.and().andEqualTo("password", appendixQuery.getPassword());
        }
        // 排序
        ExampleKit.setExampleOrder(example, appendixQuery.getOrders());
        List<AppendixDO> appendixDOList = appendixDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(appendixDOList)) {
            return appendixDOList == null ? null : new ArrayList<>();
        }
        return appendixDOList.stream()
                .map(appendixDO -> appendixDO.to(AppendixListSiteIdVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public Integer setJpgToAppendix(Long contractId, TokenUser tokenUser) {
        // 根据合同id 下载合同的对应文件
        AppendixDO appendixDO = this.selectByContractId(contractId, tokenUser.getSiteId());
        ParamException.notNull(appendixDO, "该合同没有文件，请重新发起合同");
        FileVersionDO fileVersionDO = siteFileService.download(Collections.singletonList(appendixDO.getPath()), null,
                tokenUser);
        ParamException.notNull(fileVersionDO, "文件不存在或已删除");
        File pdf = new File(fileVersionDO.getTempFilePath());
        // pdf转图片
        String fileName = System.currentTimeMillis() + ".jpg";
        String filePath = fileProperties.getTempPath() + File.separator + fileName;
        File file = new File(filePath);
        PdfUtil.pdf2multiImage(pdf.getAbsolutePath(), filePath, 80);
        MultipartFile[] multipartFiles = new MultipartFile[1];
        try {
            FileInputStream fileInputStreamTwo = new FileInputStream(file);
            MultipartFile multipartFile = new MockMultipartFile("copy" + file.getName(), file.getName(),
                    ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStreamTwo);
            multipartFiles[0] = multipartFile;
        } catch (IOException e) {
            e.printStackTrace();
            throw new ParamException("文件转化失败!");
        }
        List<String> downloadReport = siteFileService.upload(multipartFiles, "attachment", tokenUser);
        // 删除生成的图片
        file.delete();
        // 修改合同文件图片地址
        AppendixUpdateDTO appendixUpdateDTO = new AppendixUpdateDTO();
        appendixUpdateDTO.setId(appendixDO.getId());
        appendixUpdateDTO.setName(downloadReport.get(0));
        return this.update(appendixUpdateDTO, tokenUser);
    }

    /**
     * 根据查询参数，构建example
     *
     * @param appendixQuery 查询参数
     * @param siteId        所属站点id
     * @return example
     */
    private Example buildExample(AppendixQuery appendixQuery, String siteId) {
        Example example = new Example(AppendixDO.class);
        example.and()
                .andEqualTo("siteId", siteId);
        if (appendixQuery.getName() != null) {
            example.and().andEqualTo("name", appendixQuery.getName());
        }
        if (appendixQuery.getContractId() != null) {
            example.and().andEqualTo("contractId", appendixQuery.getContractId());
        }
        if (appendixQuery.getCurrentPage() != null) {
            example.and().andEqualTo("currentPage", appendixQuery.getCurrentPage());
        }
        if (appendixQuery.getPath() != null) {
            example.and().andEqualTo("path", appendixQuery.getPath());
        }
        if (appendixQuery.getPassword() != null) {
            example.and().andEqualTo("password", appendixQuery.getPassword());
        }
        // 排序
        ExampleKit.setExampleOrder(example, appendixQuery.getOrders());
        return example;
    }
}




